package com.ruoyi.web.controller.system;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.ConsumeUnionLog;
import com.ruoyi.system.domain.Franchiser;
import com.ruoyi.system.domain.ProxyRecord;
import com.ruoyi.system.service.IConsumeUnionLogService;
import com.ruoyi.system.service.IFranchiserService;
import com.ruoyi.system.service.IProxyRecordService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.domain.ConsumeUnionDataResponse;
import com.ruoyi.web.controller.domain.FranchiserDataResponse;
import com.ruoyi.web.controller.domain.FranchiserPasswordUpdateVo;
import com.ruoyi.web.controller.domain.SendItemResponse;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 分销商逻辑
 */
@RestController
@RequestMapping("/system/franchiser")
public class FranchiserController extends BaseController {
    @Autowired
    private IFranchiserService franchiserService;
    @Autowired
    private IConsumeUnionLogService consumeUnionLogService;
    @Autowired
    private IProxyRecordService proxyRecordService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private TaskExecutor taskExecutor;
    @Autowired
    private RedisCache redisCache;
    @Value("${spring.messages.locale}")
    private String locale;

    private long lastPeriodTimeEnd = 0;
    private ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 4,
            new ThreadFactoryBuilder().setDaemon(true).setNameFormat("defaultScheduled-%d").build(),
            (r, executor) -> logger.error("scheduleService queue is full"));

    @PostConstruct
    public void init() {
        String[] arr = locale.split("-");
        Locale.setDefault(new Locale(arr[0], arr.length > 1 ? arr[1] : ""));
        logger.info("init locale: {}", locale);

        startDealConsumeUnionLogThread();
        startCheckFailedOrderThread();
//        Map<String, Object> body = new HashMap<>();
//        body.put("franchiserId", 0);
//        body.put("beginTime", 1746343824);
//        body.put("endTime", 1747207824);
//        body.put("queryId", 203);
//        String sign = platformService.calcSign(body);
//        System.out.println("sign: " + sign);
    }

    public void startDealConsumeUnionLogThread() {
        Thread thread1 = new Thread(() -> {
            logger.info("start consume union log thread");
            try {
                Thread.sleep(10000L);
            } catch (Exception e) {
                logger.error("startDealConsumeUnionLogThread sleep error", e);
            }

            while (true) {
                try {
                    dealConsumeUnion();
                    Thread.sleep(1000L);
                } catch (Exception e) {
                    logger.error("dealConsumeUnion error", e);
                }
            }
        });
        thread1.start();
    }

    public void startCheckFailedOrderThread() {
        Thread thread1 = new Thread(() -> {
            logger.info("start startCheckFailedOrderThread thread");
            try {
                Thread.sleep(30000L);
            } catch (Exception e) {
                logger.error("startCheckFailedOrderThread sleep error", e);
            }
            while (true) {
                try {
                    checkFailedOrder();
                    Thread.sleep(30000L);
                } catch (Exception e) {
                    logger.error("checkFailedOrder error", e);
                }
            }
        });
        thread1.start();
    }

    public List<Franchiser> getMixFranchiser(int count) {
        Franchiser franchiserSql = new Franchiser();
        franchiserSql.setLevel(5L);
        List<Franchiser> franchisers = franchiserService.selectFranchiserList(franchiserSql);
        List<Franchiser> selects = new ArrayList<>(franchisers);
        Collections.shuffle(selects);
        if (selects.size() > count) {
            selects = selects.subList(0, count);
        }
        return selects;
    }

    /**
     * 查询【请填写功能名称】列表
     */
//    @PreAuthorize("@ss.hasPermi('system:franchiser')")
    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/list")
    public TableDataInfo list(Franchiser franchiser) {
        startPage();
        List<Franchiser> list = franchiserService.selectFranchiserList(franchiser);

        if (franchiser.getFranchiserId() != null) {
            if (list.size() > 0) {
                Franchiser first = list.get(0);
                // 取主号及副号
                if (first.getPrimaryId() > 0) {
                    Franchiser mainFranchiserSql = new Franchiser();
                    mainFranchiserSql.setFranchiserId(first.getPrimaryId());
                    List<Franchiser> list3 = franchiserService.selectFranchiserList(mainFranchiserSql);
                    addList(list, list3);

                    // 对应的副号
                    Franchiser sliverFranchiser = new Franchiser();
//            sliverFranchiser.setPrimaryOrNot(0L);
                    sliverFranchiser.setPrimaryId(first.getPrimaryId());
                    List<Franchiser> list2 = franchiserService.selectFranchiserList(sliverFranchiser);
                    addList(list, list2);
                }
            }

            // 对应的副号
            Franchiser sliverFranchiser = new Franchiser();
//            sliverFranchiser.setPrimaryOrNot(0L);
            sliverFranchiser.setPrimaryId(franchiser.getFranchiserId());
            List<Franchiser> list2 = franchiserService.selectFranchiserList(sliverFranchiser);
            addList(list, list2);
        }

        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/get_war_team_list")
    public TableDataInfo getWarTeamList(Franchiser franchiser) {
        startPage();
//        franchiser.setPrimaryOrNot(1L);
        franchiser.setLevel(4L);
        franchiser.setPrimaryId(0L);
        List<Franchiser> list = franchiserService.selectFranchiserList(franchiser);

        return getDataTable(list);
    }

    //    @PreAuthorize("@ss.hasPermi('system:franchiser')")
    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(franchiserService.selectFranchiserById(id));
    }

    //    @PreAuthorize("@ss.hasPermi('system:franchiser')")
    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Franchiser franchiser) {
        Franchiser f = franchiserService.selectFranchiserById(franchiser.getId());
        if (f.getPrimaryId() != (long) franchiser.getPrimaryId()) {
            // 设置为主号时会把主号及名下所有的副号全部换绑到这个号上
            if (franchiser.getPrimaryId() == 0) {
                Franchiser oldPrimarySql = new Franchiser();
                oldPrimarySql.setFranchiserId(f.getPrimaryId());
                List<Franchiser> list1 = franchiserService.selectFranchiserList(oldPrimarySql);
                if (list1.size() > 0) {
                    Franchiser oldPrimary = list1.get(0);
                    Franchiser secondSql = new Franchiser();
                    secondSql.setPrimaryId(oldPrimary.getFranchiserId());
                    List<Franchiser> list2 = franchiserService.selectFranchiserList(secondSql);
                    list2.add(oldPrimary);
                    for (Franchiser fran : list2) {
                        if (fran.getFranchiserId() != (long) franchiser.getFranchiserId()) {
                            fran.setPrimaryId(franchiser.getFranchiserId());
                            fran.setPrimaryOrNot(0L);
                            franchiserService.updateFranchiser(fran);
                        }
                    }
                }
            } else if (f.getPrimaryId() == 0) {
                // 设置为副号时，如果该账号原本是主号 则需要把名下所有副号也全部迁移至新号
                if (franchiser.getPrimaryId() == (long) franchiser.getFranchiserId()) {
                    return error("主号ID有误");
                }
                Franchiser newPrimarySql = new Franchiser();
                newPrimarySql.setFranchiserId(franchiser.getPrimaryId());
                List<Franchiser> list1 = franchiserService.selectFranchiserList(newPrimarySql);
                if (list1.isEmpty()) {
                    return error("主号ID有误");
                }
                Franchiser newPrimary = list1.get(0);
                if (newPrimary.getPrimaryId() > 0) {
                    return error("" + newPrimary.getFranchiserId() + "是副号,无法设置成主号");
                }
                if (newPrimary.getLevel() != 2) {
                    return error("" + newPrimary.getFranchiserId() + "等级不为2,无法设置成主号");
                }
                Franchiser secondSql = new Franchiser();
                secondSql.setPrimaryId(f.getFranchiserId());
                List<Franchiser> list2 = franchiserService.selectFranchiserList(secondSql);
                for (Franchiser fran : list2) {
                    if (fran.getFranchiserId() != (long) franchiser.getFranchiserId()) {
                        fran.setPrimaryId(franchiser.getPrimaryId());
                        fran.setPrimaryOrNot(0L);
                        franchiserService.updateFranchiser(fran);
                    }
                }
            }
        }

        return toAjax(franchiserService.updateFranchiser(franchiser));
    }

    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/update_password")
    public synchronized AjaxResult updatePassword(FranchiserPasswordUpdateVo vo) {
        if (!Helper.isValidPassword(vo.getPassword())) {
            return error("密码为8-16位,需包含数字和字母");
        }

        Franchiser franchiser = franchiserService.selectFranchiserById(vo.getId());
        if (franchiser == null) {
            return error("参数异常");
        }
        if (franchiser.getPhone() == null || franchiser.getPhone().isEmpty()) {
            return error("缺少手机号作为登录账号");
        }

        SysUser sysUser = sysUserService.selectUserByUserName(franchiser.getPhone());
        if (sysUser == null) {
            sysUser = new SysUser();
            String username = franchiser.getPhone();
            sysUser.setUserName(username);
            sysUser.setNickName(username);
            sysUser.setPassword(SecurityUtils.encryptPassword(vo.getPassword()));
            boolean regFlag = userService.registerUser(sysUser);
            if (!regFlag) {
                return error("注册失败,请联系系统管理人员");
            }
            // 设置权限
//        userService.checkUserDataScope(sysUser.getUserId());
            userService.insertUserAuth(sysUser.getUserId(), Constants.getRole(Constants.ROLE_SELLER));
            return success();
        }
        sysUser.setPassword(SecurityUtils.encryptPassword(vo.getPassword()));
        sysUser.setUpdateBy(getUsername());
        return toAjax(sysUserService.resetPwd(sysUser));
    }

    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/fetch_franchiser_task")
    public AjaxResult fetchAllFranchiserTask() {
        String key = "fetch_all_franchiser_lock";
        Long value = redisCache.getCacheObject(key);
        return success(value != null ? "1" : "0");
    }

    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/delete_all_franchiser")
    public AjaxResult deleteAllFranchiser() {
        franchiserService.deleteAllFranchiser();
        return success("清空");
    }

    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @GetMapping("/fetch_all_franchiser")
    public AjaxResult fetchAllFranchiser() {
        String key = "fetch_all_franchiser_lock";
        long time = System.currentTimeMillis() / 1000L;
        Long value = redisCache.getCacheObject(key);
        if (value != null) {
            long startTime = value;//Long.parseLong(value);
            return error("正在执行..(" + (time - startTime) + "s)");
        }

        redisCache.setCacheObject(key, time, 10 * 60, TimeUnit.SECONDS);
        scheduledExecutorService.execute(() -> {
            fetchAllFranchiserByPlatformApi();
            redisCache.deleteObject(key);
        });
        return success("开始执行任务");
    }

    /**
     * 删除【请填写功能名称】
     */
//    @PreAuthorize("@ss.hasPermi('system:franchiser')")
    @PreAuthorize("@ss.hasAnyRoles('custom_admin,custom_common')")
    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(franchiserService.deleteFranchiserByIds(ids));
    }

    @Scheduled(fixedRate = 30000, initialDelay = 5000)
    public void checkFetchAllFranchiserTaskUpdate() {
        String key = "fetch_all_franchiser_lock";
        long time = System.currentTimeMillis() / 1000L;
        Long value = redisCache.getCacheObject(key);
        if (value != null) {
            // 正在执行拉取任务
            return;
        }
        redisCache.setCacheObject(key, time, 10 * 60, TimeUnit.SECONDS);
        scheduledExecutorService.execute(() -> {
            fetchAllFranchiserByPlatformApi();
            redisCache.deleteObject(key);
        });
    }

    @Scheduled(fixedRate = 5000, initialDelay = 60000)
    public void checkOrderId() {
        String key = Helper.getLastOrderIdKey();
        int queryId = 0;
        Integer value = redisCache.getCacheObject(key);
        if (value != null) {
            queryId = (int) (value);
        }
        List<ConsumeUnionDataResponse.ConsumeUnionData> consumeUnionDataList = platformService.consumeUnionDataList(0, queryId + 1);
        if (consumeUnionDataList == null || consumeUnionDataList.isEmpty()) {
            return;
        }
        int iMaxQueryId = 0;
        for (ConsumeUnionDataResponse.ConsumeUnionData d : consumeUnionDataList) {
            if (iMaxQueryId < d.getId()) {
                iMaxQueryId = (int) d.getId();
            }
        }
        redisCache.setCacheObject(key, iMaxQueryId);

        for (ConsumeUnionDataResponse.ConsumeUnionData d : consumeUnionDataList) {
            try {
                ConsumeUnionLog log1 = consumeUnionLogService.selectConsumeUnionLogById(d.getId());
                if (log1 != null) {
                    continue;
                }
                ConsumeUnionLog log = new ConsumeUnionLog();
                log.setId(d.getId());
                log.setAccount(d.getFranchiser());
                log.setCoin(d.getUnionCoin());
                log.setStartDate(d.getDate());
                log.setStartTime(d.getTime());
                log.setDealDone(0);
                log.setCreateTime(new Date(System.currentTimeMillis()));
                log.setEventTime(Helper.getUTCTimestamp(d.getTime(), "yyyy-MM-dd HH:mm:ss"));
                consumeUnionLogService.insertConsumeUnionLog(log);

                if (log.getEventTime() < Helper.getConsumePeriodTimeEnd()) {
                    redisCache.addCacheListMember(Helper.getConsumeTodoKey(), "" + log.getId());
                }
            } catch (Exception e) {
                logger.error("insertGoldExchangeLog error", e);
            }
        }
    }

    public void dealConsumeUnion() {
        // 处理周期
        final int secondsMin = 1;
        final int secondsMax = 5;
        // 上个周期的时间
        long timeEnd = Helper.getConsumePeriodTimeEnd();
        if (lastPeriodTimeEnd != timeEnd) {
            lastPeriodTimeEnd = timeEnd;
            ConsumeUnionLog sql = new ConsumeUnionLog();
            sql.setDealDone(0);
            List<String> list1 = new ArrayList<>();
            List<ConsumeUnionLog> logList = consumeUnionLogService.selectConsumeUnionLogList(sql);
            logList.sort(Comparator.comparing(ConsumeUnionLog::getEventTime));
            for (ConsumeUnionLog l : logList) {
                if (l.getEventTime() < timeEnd) {
                    list1.add("" + l.getId());
                }
            }
            redisCache.deleteObject(Helper.getConsumeTodoKey());
            if (!list1.isEmpty()) {
                redisCache.setCacheList(Helper.getConsumeTodoKey(), list1);
            }
        }

        final int onceInsertCount = 200;
        int insertCnt = 0;
        List<String> todoList = redisCache.getCacheList(Helper.getConsumeTodoKey());
        for (String str : todoList) {
            try {
                if (insertCnt >= onceInsertCount) {
                    // 等待下次tick处理数据2
                    return;
                }
                long id = Long.parseLong(str);
                ConsumeUnionLog l = consumeUnionLogService.selectConsumeUnionLogById(id);
                if (l == null || l.getDealDone() == 1 || l.getEventTime() > timeEnd) {
                    // 已经处理成功
                    redisCache.removeCacheListMember(Helper.getConsumeTodoKey(), str);
                    continue;
                }

                String strLockExpired = redisCache.getCacheObject(Helper.getConsumeLogKey(l.getAccount()));
                if (strLockExpired != null && !strLockExpired.isEmpty()) {
                    long expiredTime = Long.parseLong(strLockExpired);
                    if (System.currentTimeMillis() / 1000L < expiredTime) {
                        continue;
                    } else {
                        // 上一个发放仍未执行完成
                        List<String> ids = redisCache.getCacheList(Helper.getConsumeLogRunningKey(l.getAccount()));
                        if (ids != null && !ids.isEmpty()) {
                            continue;
                        }
                    }
                } else {
                    // 清空下任务状态
                    redisCache.deleteObject(Helper.getConsumeLogRunningKey(l.getAccount()));
                }
                insertCnt++;
                redisCache.removeCacheListMember(Helper.getConsumeTodoKey(), str);
                final ConsumeUnionLog log = l;
                final int delay = RandomUtils.nextInt(secondsMin, secondsMax);
                logger.info("onDealGoldExchangeLog deal account: " + l.getAccount() + ", id: " + l.getId() + ", delay: " + delay);
                redisCache.setCacheObject(Helper.getConsumeLogKey(l.getAccount()), "" + (System.currentTimeMillis() / 1000L + delay), 60, TimeUnit.SECONDS);
                scheduledExecutorService.schedule(() -> {
                    try {
                        onDealGoldExchangeLog(log);
                    } catch (Exception e) {
                        logger.error("onDealGoldExchangeLog error, id: {}", log.getId(), e);
                    }
                }, delay, TimeUnit.SECONDS);
            } catch (Exception e) {
                logger.error("dealConsumeUnion error, id: {}", str, e);
                redisCache.removeCacheListMember(Helper.getConsumeTodoKey(), str);
            }
        }
    }

    //    @Scheduled(fixedRate = 10000, initialDelay = 30000)
    public void checkFailedOrder() {
        ProxyRecord recordSql = new ProxyRecord();
        recordSql.setDealDone(0);
        List<ProxyRecord> list = proxyRecordService.selectProxyRecordList(recordSql);
        for (ProxyRecord record : list) {
            trySendItemByPlatform(record);
        }
    }


    private void test() {
        ProxyRecord record = new ProxyRecord();
        record.setFranchiserId(10000L);
        record.setName("test");
        record.setTargetId(10001L);
        record.setTargetName("test_1");
        record.setValue(1234567L);
        record.setTime(new Date(System.currentTimeMillis()));
        record.setDealDone(0);
        proxyRecordService.insertProxyRecord(record);
    }

    private void onDealGoldExchangeLog(ConsumeUnionLog log) {
        Franchiser lv1Franchiser = getLv1Franchiser();
        long franchiserId = log.getAccount();
        Franchiser lv2Franchiser = getLv2Franchiser(franchiserId);
        if (lv2Franchiser == null) {
            return;
        }
        List<Franchiser> franchiserList = getAllFranchiserList(lv2Franchiser.getFranchiserId());
        List<Franchiser> mixFranchiserList = getMixFranchiser(RandomUtils.nextInt(1, 3));
        // 最小单位为0.01，数值放大100倍  log.getCoin()是放大10000倍的数据
        long costValue = log.getCoin() / 100;
        onSendAllItem(franchiserId, lv1Franchiser, franchiserList, costValue);
        // 混淆供应商
        long costValueB = log.getCoin() / 100 * RandomUtils.nextLong(10, 50) / 100;
        if (costValueB < mixFranchiserList.size()) {
            mixFranchiserList = mixFranchiserList.subList(0, (int) costValueB);
        }
        onSendAllItem(franchiserId, lv1Franchiser, mixFranchiserList, costValueB);

        redisCache.expire(Helper.getConsumeLogRunningKey(log.getAccount()), 60, TimeUnit.SECONDS);

        log.setDealDone(1);
        consumeUnionLogService.updateConsumeUnionLog(log);
    }

    public void onSendAllItem(long account, Franchiser lv1Franchiser, List<Franchiser> allFranchiser, long costValue) {
        long costValueB = costValue;
        Collections.shuffle(allFranchiser);
        for (int i = 0; i < allFranchiser.size(); i++) {
            Franchiser sendFranchiser = allFranchiser.get(i);

            long value;
            if (i == allFranchiser.size() - 1) {
                value = costValueB;
            } else {
                value = RandomUtils.nextLong(1, costValueB - (allFranchiser.size() - (i + 1)) + 1);
            }
            costValueB = costValueB - value;
            onSendItem(account, lv1Franchiser, sendFranchiser, value);
        }
    }


    public void onSendItem(long account, Franchiser lv1Franchiser, Franchiser sendFranchiser, long value) {
        ProxyRecord record = new ProxyRecord();
        record.setFranchiserId(lv1Franchiser.getFranchiserId());
        record.setName(lv1Franchiser.getName());
        record.setTargetId(sendFranchiser.getFranchiserId());
        record.setTargetName(sendFranchiser.getName());
        record.setValue(value);
        record.setTime(new Date(System.currentTimeMillis()));
        record.setDealDone(0);
        record.setAccount(account);
        proxyRecordService.insertProxyRecord(record);

        redisCache.addCacheListMember(Helper.getConsumeLogRunningKey(account), "" + sendFranchiser.getFranchiserId());

        taskExecutor.execute(() -> {
            trySendItemByPlatform(record);
        });
    }

    public void trySendItemByPlatform(ProxyRecord record) {
        String lockKey = Helper.getProxyRecordLockKey(record.getId());
        if (!redisCache.tryLock(lockKey, "" + System.currentTimeMillis() / 1000L, 60 * 5)) {
            return;
        }
        // 这里为了防止sendItem API延时高，加多一道检查，避免重试订单逻辑那里拿到过期(已处理完成)的订单
        record = proxyRecordService.selectProxyRecordById(record.getId());
        if (record == null || record.getDealDone() == 1) {
            return;
        }

        long logFranchiserId = record.getFranchiserId();
        long logTargetId = record.getTargetId();

        // 放大10000倍， getValue是放大100倍的数据
        SendItemResponse response = platformService.sendItem((int) logFranchiserId, (int) logTargetId, (double) record.getValue() * 100);
        if (response != null && response.getCode() == 0) {
            record.setDealDone(1);
            record.setDealTime(new Date());
            proxyRecordService.updateProxyRecord(record);
            redisCache.removeCacheListMember(Helper.getConsumeLogRunningKey(record.getAccount()), "" + record.getTargetId());
//            List<String> ids = redisCache.getCacheList(Helper.getConsumeLogRunningKey(record.getAccount()));
//            if (ids != null && ids.isEmpty()) {
//                redisCache.deleteObject(Helper.getConsumeLogRunningKey(record.getAccount()));
//            }
        }
    }

    private void fetchAllFranchiserByPlatformApi() {
        int page = 0;
        while (true) {
            page++;
            logger.info("获取页数:" + page);
            try {
                List<FranchiserDataResponse.FranchiserData> franchiserDataList = platformService.franchiserList(0, page);
                if (franchiserDataList == null || franchiserDataList.isEmpty()) {
                    logger.info("获取页数done.");
                    break;
                }
                for (FranchiserDataResponse.FranchiserData f : franchiserDataList) {
                    Franchiser franchiser = new Franchiser();
                    franchiser.setFranchiserId((long) f.getFranchiserId());
                    List<Franchiser> list = franchiserService.selectFranchiserList(franchiser);
                    if (list != null && list.size() > 0) {
                        franchiser = list.get(0);
                        // 有变更需要更新资料
                        if (franchiser.getLevel() != f.getLv() || !franchiser.getName().equals(f.getName()) || !franchiser.getPhone().equals(f.getContact()) || (long) (franchiser.getAgentUpline()) != (long) f.getAgentUpline()) {
                            franchiser.setLevel((long) f.getLv());
                            franchiser.setName(f.getName());
                            franchiser.setPhone(f.getContact());
                            franchiser.setAgentUpline((long) f.getAgentUpline());
                            franchiserService.updateFranchiser(franchiser);
                        }
                    } else {
                        franchiser.setName(f.getName() == null ? "" + f.getFranchiserId() : f.getName());
                        franchiser.setPhone(f.getContact());
                        franchiser.setLevel((long) f.getLv());
                        franchiser.setAgentUpline((long) f.getAgentUpline());
                        franchiserService.insertFranchiser(franchiser);
                    }
                }
            } catch (Exception e) {
                logger.error("fetchAllFranchiserByPlatformApi error", e);
            }
        }
    }

    public Franchiser getLv1Franchiser() {
        Franchiser franchiserSql = new Franchiser();
        franchiserSql.setLevel(1L);
        List<Franchiser> franchisers = franchiserService.selectFranchiserList(franchiserSql);
        if (franchisers != null) {
            return franchisers.get(0);
        }
        return null;
    }

    public Franchiser getLv2Franchiser(long franchiserId) {
        Franchiser franchiserSql = new Franchiser();
        franchiserSql.setFranchiserId(franchiserId);
        List<Franchiser> franchisers = franchiserService.selectFranchiserList(franchiserSql);
        if (franchisers != null && !franchisers.isEmpty()) {
            Franchiser franchiser = franchisers.get(0);
            if (franchiser.getLevel() != 2 && franchiser.getLevel() != 4) {
                logger.error("franchiserId: " + franchiserId + ", level error, level = " + franchiser.getLevel());
                return null;
            }
            if (franchiser.getLevel() == 4) {
                if (franchiser.getAgentUpline() <= 0) {
                    logger.error("franchiserId: " + franchiserId + ", agentUpline invalid, = " + franchiser.getAgentUpline());
                    return null;
                }
                Franchiser franchiserSql1 = new Franchiser();
                franchiserSql1.setFranchiserId(franchiser.getAgentUpline());
                franchisers = franchiserService.selectFranchiserList(franchiserSql1);
                if (franchisers != null && !franchisers.isEmpty()) {
                    Franchiser lv2Franchiser = franchisers.get(0);
                    if (lv2Franchiser.getLevel() != 2) {
                        logger.error("franchiserId: " + franchiserId + ", agentUpline: " + franchiser.getAgentUpline() + ", level error, = " + lv2Franchiser.getLevel());
                        return null;
                    }
                    return lv2Franchiser;
                }
            }
            return franchisers.get(0);
        }
        return null;
    }

    public List<Franchiser> getAllFranchiserList(long franchiserId) {
        Franchiser franchiserSql1 = new Franchiser();
        franchiserSql1.setFranchiserId(franchiserId);

        List<Franchiser> list = franchiserService.selectFranchiserList(franchiserSql1);
        Franchiser franchiserSql2 = new Franchiser();
        franchiserSql2.setPrimaryId(franchiserId);
        list.addAll(franchiserService.selectFranchiserList(franchiserSql2));

        return list;
    }

    public void addList(List<Franchiser> list1, List<Franchiser> list2) {
        for (Franchiser f2 : list2) {
            boolean bReplace = false;
            for (Franchiser f1 : list1) {
                if (f1.getFranchiserId() == (long) f2.getFranchiserId()) {
                    bReplace = true;
                    break;
                }
            }
            if (!bReplace) {
                list1.add(f2);
            }
        }
    }
}
